import router from "../router"
import axios, { AxiosError, AxiosInstance, AxiosPromise, AxiosRequestConfig, AxiosResponse } from 'axios';

export interface IDataWithError<T> {
  data: T;
  code: number;
  msg: string;
}

class HttpService {
  private http!: AxiosInstance;

  constructor() {
    this.http = axios.create({
      baseURL: 'http://www.cloudiip.local',
      timeout: 60000,
    });
    this.addInterceptors(this.http);
  }

  get<T>(url: string, param: object) {
    return this.handleErrorWrapper<T>(this.http.get(url, param));
  }

  post<T>(url: string, param: unknown, config?: AxiosRequestConfig) {
    return this.handleErrorWrapper<T>(this.http.post(url, param, config));
  }

  postDownload<T>(url: string, param: unknown) {
    return this.handleErrorWrapper<T>(this.http.post(url, param, { responseType: 'arraybuffer' }));
  }

  put<T>(url: string, param: unknown, config?: AxiosRequestConfig) {
    return this.handleErrorWrapper<T>(this.http.put(url, param, config));
  }

  delete<T>(url: string, param: unknown, config?: AxiosRequestConfig) {
    return this.handleErrorWrapper<T>(this.http.delete(url, { data: param, ...config }));
  }

  private addInterceptors(http: AxiosInstance) {
    // 一、请求拦截器
    http.interceptors.request.use((config) => {
      // 1、添加token和项目id
      const token = 'token';
      if (token) {
        config.headers!['Authorization'] = 'Bearer ' + token;// !告诉ts这个headers一定存在，否则会报Object is possibly ‘undefined’
        config.headers!['ProjectId'] = '';
      }
      // 2、验证请求状态码
      config.validateStatus = (status) => {
        switch (status) {
          case 401:
            alert('用户信息过期，请重新登录')
            setTimeout(() => {
              router.push('/login');
            }, 1000);
            break;
          default:
            console.warn(`status= ${status}`);
            break;
        }
        return status >= 200 && status < 400;
      };

      return config;
    });

    // 二、响应拦截器
    http.interceptors.response.use(
      (response: AxiosResponse) => {
        console.log('响应成功')
        return response;
      },
      (error) => {
        console.log('响应失败')
        return Promise.reject(error);
      },
    );
  }

  private async handleErrorWrapper<T>(p: AxiosPromise): Promise<IDataWithError<T>> {
    return p
      .then((response) => {
        return response.data;
      })
      .catch((error: AxiosError) => {
        return error.message;
      });
  }
}

export const httpService = new HttpService();

